var validator = require('../validator')

function HashMap() {
    this.map = {};
}
HashMap.prototype = {
    put: function(key, value) { // 向Map中增加元素（key, value) 
        this.map[key] = value;
    },
    get: function(key) { //获取指定Key的元素值Value，失败返回Null 
        if (this.map.hasOwnProperty(key)) {
            return this.map[key];
        }
        return null;
    },
    remove: function(key) { // 删除指定Key的元素，成功返回True，失败返回False
        if (this.map.hasOwnProperty(key)) {
            return delete this.map[key];
        }
        return false;
    },
    removeAll: function() { //清空HashMap所有元素
        this.map = {};
    },
    keySet: function() { //获取Map中所有KEY的数组（Array） 
        var _keys = [];
        for (var i in this.map) {
            _keys.push(i);
        }
        return _keys;
    }
};

HashMap.prototype.constructor = HashMap;

// 观察者列表
var _observerCache = new HashMap();

/// 需要删除的列表
/// 直接删除由于在notifyStateChanged方法中存在遍历情况，
/// 会导致并发异常,所以讲要删除的观察者先放入要删除的列表中
/// 在下次发通知的时候先删除已删除的观察者
var _observerRemoveCache = new Array();

/**
 * 清空需要删除的观察者
 */
const _clearObserversNeedToRemove =()=>{

    _observerRemoveCache.forEach(httpObserver=>{

        var observerList = _observerCache.get(httpObserver.url)

        if(validator.isNullOrEmpty(observerList)) return

        var index = observerList.indexOf(httpObserver);
        if (index > -1) {
            observerList.splice(index, 1);
        }
    })

    _observerRemoveCache.length = 0
}

/**
 * 通知状态发生改变
 * @param {通讯状态} communicationState 
 * @param {请求信息} resquest 
 * @param {请求返回信息} response 
 */
const notifyStateChanged=(communicationState, request, response)=>{
    
    _clearObserversNeedToRemove()

    if(validator.isNullOrEmpty(request.url)) return

    var observerList = _observerCache.get(request.url)
    if(validator.isNullOrEmpty(observerList)) return

    // 通知遍历观察者
    observerList.forEach(httpObserver=>{

        if(validator.isFunction(httpObserver.onCommunicationStateChangedCallBack)){
            httpObserver.onCommunicationStateChangedCallBack(
                communicationState, request, response
            )
        }
    })
}

/**
 * 添加观察者
 * @param {请求地址} url 
 * @param {请求状态发生改变回调} onCommunicationStateChangedCallBack 
 */
const addObserver=(httpObserver)=>{

    _clearObserversNeedToRemove()

    if(!validator.isNullOrEmpty(httpObserver.url) 
    && validator.isFunction(httpObserver.onCommunicationStateChangedCallBack)){

        var observerList = _observerCache.get(httpObserver.url)

        if(validator.isNullOrEmpty(observerList)){

            // 空则添加一个
            observerList = new Array()
            _observerCache.put(httpObserver.url, observerList)
        }

        // 如果已经有了，就不用重复添加观察
        if(observerList.indexOf(httpObserver) > -1){
            return
        }
        
        observerList.push(httpObserver)
    }else{
        console.log("请以字典的形式定义httpObserver，并设置url和onCommunicationStateChangedCallBack两个字段")
    }
}

/**
 * 移除观察者
 * @param {通讯观察者}} httpObserver 
 */
const removeObserver=(httpObserver)=>{

    if(validator.isNullOrEmpty(httpObserver.url)) return 

    var observerList = _observerCache.get(httpObserver.url)
    if(validator.isNullOrEmpty(observerList.indexOf(httpObserver) === -1)) return

    if(_observerRemoveCache.indexOf(httpObserver) === -1) return

    // 添加到删除列表
    /// 直接删除由于在notifyStateChanged方法中存在遍历情况，
    /// 会导致并发异常,所以讲要删除的观察者先放入要删除的列表中
    /// 在下次发通知的时候先删除已删除的观察者
    _observerRemoveCache.put(httpObserver)
}

module.exports = {
    notifyStateChanged,
    addObserver,
    removeObserver
}